package fileattrfilter

import (
	"strconv"
	"strings"

	"gitee.com/guoliben/kydlp-doctotext/utils/ctrlledprint"
)

const (
	JudgingConditionEqualTo int = iota + 1
	JudgingConditionNotEqualTo
	JudgingConditionGreater
	JudgingConditionGreaterEqual
	JudgingConditionLess
	JudgingConditionLessEqual
	JudgingConditionInRange
	JudgingConditionNotInRange
	JudgingConditionInList
	JudgingConditionNotInList
)

type FilesizeFilterRuleObject struct {
	Mimetype      string
	Condition     string
	ConditionType int
}

type FilesizeFilterRule struct {
        Body FilesizeFilterRuleObject
}

var filesizefilterrule = FilesizeFilterRule{
	Body: FilesizeFilterRuleObject{
		Mimetype: "", // 不为空即对指定类型的文件进行大小过滤，否则即对所有类型的文件进行大小过滤
		Condition: "1073741824",
		ConditionType: JudgingConditionGreaterEqual,
	},
}

func FilterExcludeFilesize(filetype string, size int64) bool {
	ctrlledprint.Println("过滤文件大小...")

	conditionoperands := strings.Split(filesizefilterrule.Body.Condition, ",")
	conditiontype := filesizefilterrule.Body.ConditionType
	if len(filesizefilterrule.Body.Mimetype) > 0 {
		if filetype == filesizefilterrule.Body.Mimetype {
			if conditionFilter(conditiontype, conditionoperands, size) {
				ctrlledprint.Println("文件大小:", size, "触发文件大小例外规则，将对其进行放行处理，不做内容检测！")
				return true
			} else {
				return false
			}
		} else {
			return false
		}
	} else {
		if conditionFilter(conditiontype, conditionoperands, size) {
			ctrlledprint.Println("文件大小:", size, "触发文件大小例外规则，将对其进行放行处理，不做内容检测！")
			return true
		} else {
			return false
		}
	}

	return false
}

func conditionFilter(conditionoperator int, conditionoperands []string, size int64) bool {
	operandcount := len(conditionoperands)
	if (operandcount == 1) {
		//operand, err := strconv.Atoi(conditionoperands[0])
		operand, err := strconv.ParseInt(conditionoperands[0], 10, 64)
		if err != nil {
			ctrlledprint.Println("文件大小过滤规则操作符转换错误:", err)
			return false
		}
		switch conditionoperator {
		case JudgingConditionEqualTo:
			if size == operand {
				return true
			} else {
				return false
			}
		case JudgingConditionNotEqualTo:
			if size != operand {
				return true
			} else {
				return false
			}
		case JudgingConditionGreater:
			if size > operand {
				return true
			} else {
				return false
			}
		case JudgingConditionGreaterEqual:
			if size >= operand {
				return true
			} else {
				return false
			}
		case JudgingConditionLess:
			if size < operand {
				return true
			} else {
				return false
			}
		case JudgingConditionLessEqual:
			if size <= operand {
				return true
			} else {
				return false
			}
		}
	} else if (operandcount == 2) {
		//operand1, err1 := strconv.Atoi(conditionoperands[0])
		//operand2, err2 := strconv.Atoi(conditionoperands[1])
		operand1, err1 := strconv.ParseInt(conditionoperands[0], 10, 64)
		operand2, err2 := strconv.ParseInt(conditionoperands[1], 10, 64)
		if err1 != nil || err2 != nil {
			ctrlledprint.Println("文件大小过滤规则操作符转换错误:", err1, err2)
			return false
		}
		switch conditionoperator {
		case JudgingConditionInRange:
			if size >= operand1 && size <= operand2 {
				return true
			} else {
				return false
			}
		case JudgingConditionNotInRange:
			if size < operand1 || size > operand2 {
				return true
			} else {
				return false
			}
		case JudgingConditionInList:
			in := false
			for _, conditionoperand := range conditionoperands {
				//operand, _ := strconv.Atoi(conditionoperand)
				operand, err := strconv.ParseInt(conditionoperand, 10, 64)
				if err != nil {
					ctrlledprint.Println("文件大小过滤规则操作符转换错误:", err)
					return false
				}
				if size == operand {
					in = true
					break
				}
			}
			if in {
				return true
			} else {
				return false
			}
		case JudgingConditionNotInList:
			notin := true
			for _, conditionoperand := range conditionoperands {
				//operand, _ := strconv.Atoi(conditionoperand)
				operand, err := strconv.ParseInt(conditionoperand, 10, 64)
				if err != nil {
					ctrlledprint.Println("文件大小过滤规则操作符转换错误:", err)
					return false
				}
				if size == operand {
					notin = false
					break
				}
			}
			if notin {
				return true
			} else {
				return false
			}
		}
	} else if (operandcount > 2) {
		switch conditionoperator {
		case JudgingConditionInList:
			in := false
			for _, conditionoperand := range conditionoperands {
				//operand, _ := strconv.Atoi(conditionoperand)
				operand, err := strconv.ParseInt(conditionoperand, 10, 64)
				if err != nil {
					ctrlledprint.Println("文件大小过滤规则操作符转换错误:", err)
					return false
				}
				if size == operand {
					in = true
					break
				}
			}
			if in {
				return true
			} else {
				return false
			}
		case JudgingConditionNotInList:
			notin := true
			for _, conditionoperand := range conditionoperands {
				//operand, _ := strconv.Atoi(conditionoperand)
				operand, err := strconv.ParseInt(conditionoperand, 10, 64)
				if err != nil {
					ctrlledprint.Println("文件大小过滤规则操作符转换错误:", err)
					return false
				}
				if size == operand {
					notin = false
					break
				}
			}
			if notin {
				return true
			} else {
				return false
			}
		}
	} else {
		ctrlledprint.Println("文件大小过滤规则有误，请检查！")
	}

	return false
}
